#include "cgzCLua.h"
#include "cgzCThreadPool.h"

bool cgzCLua::run(const cgzITask *iTask, cgzCHttpLoopS *ask)
{
    switch (ask->m_cmd)
    {
    case EHTTP_S::HTTPS_LISTEN:
    {
        auto listen = static_cast<cgzCHttpListenS *>(ask);
        ocall(iTask->m_tref, "listen", {listen->m_success});
        return true;
    }
    case EHTTP_S::HTTPS_RGET:
    {
        auto recv_get = static_cast<cgzCHttpRGetS *>(ask);
        ocall(iTask->m_tref, "reply", {(const void *)ask, "get", recv_get->m_uri.c_str(), recv_get->m_params});
        break;
    }
    case EHTTP_S::HTTPS_RPOST:
    {
        auto recv_post = static_cast<cgzCHttpRPostS *>(ask);
        ocall(iTask->m_tref, "reply", {(const void *)ask, "post", recv_post->m_uri.c_str(), recv_post->m_params});
        break;
    }
    case EHTTP_S::HTTPS_RPUT:
    {
        auto recv_put = static_cast<cgzCHttpRPutS *>(ask);
        ocall(iTask->m_tref, "reply", {(const void *)ask, "put", recv_put->m_uri.c_str(), recv_put->m_params});
        break;
    }
    case EHTTP_S::HTTPS_RDEL:
    {
        auto recv_del = static_cast<cgzCHttpRDelS *>(ask);
        ocall(iTask->m_tref, "reply", {(const void *)ask, "del", recv_del->m_uri.c_str(), recv_del->m_params});
        break;
    }
    case EHTTP_S::HTTPS_RHEAD:
    {
        auto recv_head = static_cast<cgzCHttpRHeadS *>(ask);
        ocall(iTask->m_tref, "reply", {(const void *)ask, "head", recv_head->m_uri.c_str(), recv_head->m_params});
        break;
    }
    case EHTTP_S::HTTPS_ROPTS:
    {
        auto recv_opts = static_cast<cgzCHttpROptsS *>(ask);
        ocall(iTask->m_tref, "reply", {(const void *)ask, "opts", recv_opts->m_uri.c_str(), recv_opts->m_params});
        break;
    }
    default:
    {
        cgz_this_error("Unknown HTTP command. task:{}", iTask->getName());
    }
    }
    return false;
}

static int https_new(lua_State *L)
{
    // 将其转换为 cgzCLua 指针
    cgzCLua *that = cgzCLua::getThat(L);
    const char *name = lua_tostring(L, 1);
    const char *url = lua_tostring(L, 2);
    int tref = luaL_ref(L, LUA_REGISTRYINDEX);
    void *node = malloc(sizeof(cgzCHttpS));
    auto cobj = new (node) cgzCHttpS(that->m_pool, name, url, that->getId());
    cobj->m_tref = tref;
    return 0;
}

static int https_ret(lua_State *L)
{
    // 将其转换为 cgzCLua 指针
    cgzCLua *that = cgzCLua::getThat(L);
    size_t len = 0;
    auto ask = (cgzCHttpRecvS *)(lua_topointer(L, 1));
    const char *ret = lua_tolstring(L, 2, &len);
    ask->m_retstr.clear();
    ask->m_retstr.append(ret, len);
    that->todoret(ask);
    return 0;
}

static int https_set(lua_State *L)
{
    // 将其转换为 cgzCLua 指针
    cgzCLua *that = cgzCLua::getThat(L);
    void *node = malloc(sizeof(cgzCHttpCorsS));
    auto ask = new (node) cgzCHttpCorsS();
    const char *name = lua_tostring(L, 1);
    // 遍历table
    lua_pushnil(L);
    while (lua_next(L, 2))
    {
        const char *key = lua_tostring(L, -2);
        const char *value = lua_tostring(L, -1);
        ask->m_cors[key] = value;
        lua_pop(L, 1);
    }
    that->regTask(name, ask);
    return 0;
}

int cgzCLua::luaopen_httpS(lua_State *L)
{
    static const luaL_Reg otherlib[] = {
        {"new", https_new},
        {"ret", https_ret},
        {"set", https_set},
        {NULL, NULL}};

    luaL_newlib(L, otherlib);
    return 1;
}